package jfuzzyprincepless.zarchive.algorithm.structure.forcnstr;


import jfuzzyprincepless.zarchive.algorithm.structure.ChainCommand;
import jfuzzyprincepless.zarchive.negotiation.protocols.propositionnetwork.DefaultNegotiation__Q;
import jfuzzyprincepless.zarchive.negotiation.IAgentsExporter;
import jfuzzyprincepless.negotiation.IExecutionContext;
import jfuzzyprincepless.negotiation.INegotiation;
import jfuzzyprincepless.negotiation.INegotiationContext;

/**
 * @see jfprincesstests.structures.negotiation.TestForConstruction#testDefaultForLoopRunnable()
 */
public class DefaultForLoopRunnable
	implements Runnable
{
	public static final DefaultForLoopRunnable NOP =
		new DefaultForLoopRunnable();

	private INegotiation subnegotiation;

	private boolean negotiate;
	private INegotiationContext negotiationContext;

	private boolean execute;
	private IExecutionContext executionContext;

	/**
	 * in {@link #run()} calls both negotiation and execution
	 */
	public DefaultForLoopRunnable(
		INegotiation subnegotiation,
		INegotiationContext negotiationContext,
		IExecutionContext executionContext
	) {
		this.subnegotiation = subnegotiation;
		iniNegotiate(negotiationContext);
		initExecute(executionContext);
	}

	/**
	 * in {@link #run()} calls negotiation
	 */
	public DefaultForLoopRunnable(
		INegotiation subnegotiation,
		INegotiationContext context
	) {
		this.subnegotiation = subnegotiation;
		iniNegotiate(context);
	}

	/**
	 * in {@link #run()} calls execution
	 */
	public DefaultForLoopRunnable(
		INegotiation subnegotiation,
		IExecutionContext context
	) {
		this.subnegotiation = subnegotiation;
		initExecute(context);
	}

	/**
	 * NOP
	 */
	private DefaultForLoopRunnable() {
		this.subnegotiation = new DefaultNegotiation__Q(
			new ChainCommand(),
			IAgentsExporter.EMPTY_EXPORTER
		);
	}

	@Override
	public void run() {
		if (negotiate) {
			subnegotiation.negotiate(negotiationContext);
		}
		if (execute) {
			subnegotiation.execute(executionContext);
		}
	}

	public INegotiation getSubnegotiation() {
		return subnegotiation;
	}

	public void setNegotiationContext(INegotiationContext negotiationContext) {
		this.negotiationContext = negotiationContext;
	}

	public void setExecutionContext(IExecutionContext executionContext) {
		this.executionContext = executionContext;
	}

	private void iniNegotiate(
		INegotiationContext negotiationContext
	) {
		this.negotiationContext = negotiationContext;
		negotiate = true;
	}

	private void initExecute(
		IExecutionContext executionContext
	) {
		this.executionContext = executionContext;
		execute = true;
	}
}
